package com.eunion.boot;

import java.beans.PropertyVetoException;
import java.util.List;
import java.util.Locale;

import javax.servlet.MultipartConfigElement;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.eunion.boot.settings.datasource.IDruidDataSource;
import com.eunion.boot.spring.ProjectSettings;
import com.eunion.core.LogUtil;

/**
 * WEB MVC Configuration.
 * @version 2015年7月22日 http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc 异常处理 http://www.cnblogs.com/thefun/p/3326373.html 404 异常问题
 *          http://doc.okbase.net/catoop/archive/206065.html jsonp
 */
@Configuration
@EnableWebMvc
public class ConfigurerAdapter extends WebMvcConfigurerAdapter {

    @Autowired
    private IDruidDataSource druidDataSource;

    @Autowired
    ProjectSettings projectSettings;

    @Bean
    public DruidDataSource dataSource()
        throws PropertyVetoException {
        return druidDataSource.dataSource();
    }

    // @Bean //事务http://blog.csdn.net/catoop/article/details/50595702
    // public Object tesGetManager(PlatformTransactionManager platformTransactionManager) {
    // LogUtil.get(this.getClass()).info(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
    // return new Object();
    // }

    @Bean
    InternalResourceViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        LogUtil.get(this.getClass()).debug("projectSettings.getFilePath() is :{}", projectSettings.getFilePath());
        registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/static/assets/").setCachePeriod(31556926);// .setCachePeriod(31556926);
        registry.addResourceHandler("/files/**").addResourceLocations("file:" + projectSettings.getFilePath()).setCachePeriod(31556926);
        // registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/webjars/");
        if (!registry.hasMappingForPattern("/webjars/**")) {
            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/").setCachePeriod(31556926);// 1-year
        }
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // registry.addViewController("/home").setViewName("home");
        // registry.addViewController("/").setViewName("home");
        // registry.addViewController("/about").setViewName("about");
        // registry.addViewController("/login").setViewName("login");
        // registry.addViewController("/e-500").setViewName("e-500");
        // registry.addViewController("/e-404").setViewName("e-404");
        // registry.addViewController("/index.html").setViewName("index");
        // registry.addViewController("/home").setViewName("home");
        // // registry.addViewController("/").setViewName("home");
        // registry.addViewController("/").setViewName("forward:/index.html");
        // registry.addViewController("/auth").setViewName("auth");
        // registry.addViewController("/login").setViewName("login");
        // // registry.addViewController("/error").setViewName("login");
        // registry.addViewController("/loginout").setViewName("login");
    }

    @Bean
    public MultipartConfigElement multipartConfigElement() {
        // MultipartConfigFactory factory = new MultipartConfigFactory();
        // factory.setMaxFileSize("12800KB");
        // factory.setMaxRequestSize("12800KB");
        // return factory.createMultipartConfig();
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // factory.setMaxFileSize("50MB");
        // factory.setMaxRequestSize("50MB");
        return factory.createMultipartConfig();
        // return new MultipartConfigElement("");
    }

    @Bean
    public MultipartResolver multipartResolver() {
        org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
        // multipartResolver.setMaxUploadSize(1000000);
        return multipartResolver;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty);
//        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
//        fastJsonConfig.setSerializerFeatures(SerializerFeature.NotWriteDefaultValue);
//        fastJsonConfig.setSerializerFeatures(SerializerFeature.EMPTY);
        fastConverter.setFastJsonConfig(fastJsonConfig);

        converters.add(fastConverter);
    }

//    @Override
//    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//        final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//        final ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//        converter.setObjectMapper(objectMapper);
//        converters.add(converter);
//        super.configureMessageConverters(converters);
//    }
    
    // http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
    // The defaultErrorView property is especially useful as it ensures any uncaught exception generates a
    // suitable application defined error page. (The default for most application servers is to display a
    // Java stack-trace - something your users should never see).
    @Bean(name = "simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
        return new SysSimpleMappingExceptionResolver();
        // SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
        // Properties mappings = new Properties();
        // //http://www.cnblogs.com/thefun/p/3326373.html
        // mappings.setProperty("org.springframework.security.access.AccessDeniedException", "admin/403");
        // mappings.setProperty("NoSuchRequestHandlingMethodException", "404");
        // mappings.setProperty("java.lang.Throwable", "500");
        // r.setExceptionMappings(mappings); // None by default
        // r.setDefaultErrorView("error"); // No default
        // r.setExceptionAttribute("ex"); // Default is "exception"
        // r.setWarnLogCategory("example.MvcLogger"); // No default
        // return r;
    }

    /**
     * 配置拦截器 http://lihao312.iteye.com/blog/2078139
     */
    @Override
    public void addInterceptors(final InterceptorRegistry registry) {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        registry.addInterceptor(localeChangeInterceptor);
        // 1.spring boot拦截器默认有
        // HandlerInterceptorAdapter
        // AbstractHandlerMapping
        // UserRoleAuthorizationInterceptor
        // LocaleChangeInterceptor
        // ThemeChangeInterceptor
        // registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
        // registry.addInterceptor(new UserSecurityInterceptor()).addPathPatterns("/user/**");
        // registry.addInterceptor(new ExecuteTimeInterceptor()).addPathPatterns("/**");
        // registry.addInterceptor(new LogMDCInterceptor()).addPathPatterns("/**");// .excludePathPatterns("/api/**");
        // registry.addInterceptor(new LocaleInterceptor());
        // registry.addInterceptor(new
        // ThemeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");
        // registry.addInterceptor(new
        // SecurityInterceptor()).addPathPatterns("/secure/*");
    }

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
        sessionLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return sessionLocaleResolver;
        // CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
        // cookieLocale Resolver.setDefaultLocale(StringUtils.parseLocaleString("zh_CN"));
        // return cookieLocaleResolver;
    }

    /**
     * http://localhost:8080/UDCMS/admin/?lang=en_US http://localhost:8080/UDCMS/admin/?lang=zh_CN
     * @return
     */
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        // messageSource.setBasenames("classpath:messages","classpath:i18n/resource");//, "classpath:messages/validation");
        messageSource.setBasenames("classpath:i18n/resource");// , "classpath:messages/validation");
        // if true, the key of the message will be displayed if the key is not
        // found, instead of throwing a NoSuchMessageException
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.setDefaultEncoding("UTF-8");
        // # -1 : never reload, 0 always reload
        messageSource.setCacheSeconds(0);
        return messageSource;
    }

}
